﻿using System.Collections.Generic;

public class GameActor : IGameActor
{
    protected List<IGameComponent> components = ListPool<IGameComponent>.Get();

    public virtual void Awake()
    {
        
    }
    
    public IGameComponent AddComponent(IGameComponent component)
    {
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to AddComponent.");
            return null;
        }

        if (components.Contains(component))
        {
            GLog.Warning("GameActor has same component but you are still trying to AddComponent.");
            return component;
        }

        components.Add(component);
        return component;
    }

    public T AddComponent<T>() where T : IGameComponent, new()
    {
        var component = new T();
        component.SetActor(this);
        components.Add(component);
        return component;
    }

    public void RemoveComponent(IGameComponent component)
    {
        component.Destroy();
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to RemoveComponent.");
            return;
        }

        components.Remove(component);
    }

    public void RemoveAllComponent()
    {
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to RemoveComponent.");
            return;
        }

        for (int i = 0; i < components.Count; i++)
        {
            components[i].Destroy();
        }
        
        components.Clear();
    }

    public T GetComponent<T>() where T : class, IGameComponent
    {
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to GetComponent<T>.");
            return null;
        }
        
        for (int i = 0; i < components.Count; i++)
        {
            if (components[i] is T)
            {
                return components[i] as T;
            }
        }

        return null;
    }

    public void UpdateLogic(float deltaTime)
    {
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to UpdateLogic.");
            return;
        }
        
        for (int i = 0; i < components.Count; i++)
        {
            components[i].UpdateComponent(deltaTime);
        }
    }

    public virtual void Destroy()
    {
        if (components == null)
        {
            GLog.Error("GameActor has been destroyed but you are still trying to Destroy.");
            return;
        }
        
        RemoveAllComponent();
        ListPool<IGameComponent>.Release(components);
        components = null;
    }
}